/*
 * Galaxium Messenger
 * Copyright (C) 2003-2007 Philippe Durand <draekz@gmail.com>
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * Copyright (C) 2007 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;
using System.Xml;

using Gdk;
using Gtk;

using Anculus.Core;

using Galaxium.Core;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;
using Galaxium.Protocol;

namespace Galaxium.Protocol.Msn.GtkGui
{
	public class EmoticonLabel: Label
	{
		public EmoticonLabel(string markup)
			: base(string.Empty)
		{
			Markup = markup;
			
			this.AppPaintable = true;
			this.ExposeEvent += OnExposeEvent;
		}
		
		int _emoticonmargin = 1;
		string _text;
		string _markup;
		
		public new string Text
		{
			get { return _text; }
			set { _text = value; }
		}

		public new string Markup
		{
			get { return _markup; }
			set
			{
				_markup = value;

				char accel_char;
				Pango.AttrList attrs;
				Pango.Global.ParseMarkup(_markup, char.MaxValue, out attrs, out _text, out accel_char);
			}
		}
		
		[GLib.ConnectBefore]
		void OnExposeEvent(object sender, Gtk.ExposeEventArgs args)
		{
			Gdk.Rectangle area = args.Event.Area;
			
			int y = (int) Ypad;
			int x = (int) Xpad;
			
			int pw, ph, lineheight = 0, totalheight = 0;
			
			Layout.Wrap = Pango.WrapMode.Word;
			
			List<ITextChunk> chunks = null;
			
			if (!string.IsNullOrEmpty (_text))
				chunks = PangoUtility.SplitMarkup (_markup, MsnProtocol.Instance, null);
			else
				chunks = new List<ITextChunk> ();
			
			foreach (ITextChunk chunk in chunks)
			{
				if (chunk.Type != TextChunkType.Emoticon)
				{
					char accel_char;
					Pango.AttrList attrs;
					string txt;
					Pango.Global.ParseMarkup (chunk.Text, char.MaxValue, out attrs, out txt, out accel_char);
					
					if (txt == "\n")
					{
						y += lineheight;
						x = (int)Xpad;
						totalheight += lineheight;
						lineheight = 0;
						continue;
					}
					
					if (string.IsNullOrEmpty (txt))
					{
						Log.Warn ("No text in markup {0}\n{1}", chunk.Text, _markup);
						continue;
					}
					
					Layout.SetText (txt);
					Layout.Attributes = attrs;
					
					Layout.GetPixelSize (out pw, out ph);
					
					if (ph > lineheight)
						lineheight = ph;

					//check if we need ellipsizing
					if (Layout.Ellipsize != Pango.EllipsizeMode.None && (area.X + x + pw) > (area.Width + area.X))
						Layout.Width = Convert.ToInt32 ((area.Width - x - 2 * Xpad) * Pango.Scale.PangoScale);
					
					//paint the layout
					Gtk.Style.PaintLayout (Style,
					                       GdkWindow,
					                       Gtk.StateType.Normal,
					                       true,
					                       area,
					                       this,
					                       "labeltext",
					                       area.X + x,
					                       area.Y + y,
					                       Layout);
					
					x += pw;
				}
				else
				{
					x += _emoticonmargin;

					Gdk.Pixbuf pixbuf = null;
					
					IEmoticon emot = ((EmoticonTextChunk)chunk).Emoticon;
					
					if (!string.IsNullOrEmpty(emot.Filename))
						pixbuf = new Pixbuf(emot.Filename);
					else
						pixbuf = new Pixbuf(emot.Data);
		 
					//TODO: newH should be the height of the font
					int newH = 16;
					int newW = (int)(((double)pixbuf.Width / (double)pixbuf.Height) * newH);
					pixbuf = pixbuf.ScaleSimple(newW, newH, InterpType.Bilinear);
						
					if (area.X + x < (area.Width + area.X))
						GdkWindow.DrawPixbuf (null, pixbuf, 0, 0, area.X + x,
						                   area.Y + y, pixbuf.Width, pixbuf.Height,
						                   RgbDither.None, 0, 0);

					x += pixbuf.Width + _emoticonmargin;
				}
			}
			
			totalheight += lineheight;
			this.HeightRequest = totalheight;
			
			args.RetVal = false;
		}
	}
}
